// electron-main/index.ts
// import type { IpcMainInvokeEvent} from 'electron';
import { Setting } from "../src/common/model/setting";
import * as PathUtils from "../src/common/utils/pathUtils";
import * as DateUtils from "/src/common/utils/DateUtils";
import { BrowserWindow, app, dialog, ipcMain } from "electron";
import fs from "fs";
import path from "path";

const { execSync, exec } = require("child_process");

// import { exec } from "*";

const WinState = require("electron-win-state").default;
// const {getSQL} = require('../src/utils/sql/sql')
// import {getSQL} from '../src/utils/sql/sql';

// 主进程
const createWindow = () => {
  const winState = new WinState({
    defaultWidth: 1000,
    defaultHeight: 800,
    electronStoreOptions: {
      name: "window-state-main",
    },
  });

  const win = new BrowserWindow({
    // width: 800,
    // height: 600
    // 自定义窗口状态
    ...winState.winOptions,

    webPreferences: {
      // contextIsolation: false, // 是否开启隔离上下文
      // nodeIntegration: true, // 渲染进程使用Node API
      webSecurity: false,
      preload: path.join(__dirname, "../dist-electron/preload.js"), // 需要引用js文件
    },
    show: false,
  });
  console.log(path.join(__dirname, "../dist-electron/preload.js"));
  winState.manage(win);

  // 优雅打开窗口
  win.on("ready-to-show", () => {
    win.show();
    // 打开开发者工具
    const wc = win.webContents;
    wc.openDevTools();

    // wc.on("context-menu", () => {
    //   // console.log(params)
    //   // wc.executeJavaScript(`alert('${params.selectionText}')`)
    //
    //   dialog
    //     .showOpenDialog({
    //       buttonLabel: "选择",
    //       defaultPath: app.getPath("desktop"),
    //       properties: ["multiSelections", "createDirectory", "openFile", "openDirectory"],
    //     })
    //     .then(result => {
    //       console.log(result);
    //     });
    //
    //   // dialog.showSaveDialog({}).then(result => {
    //   //   console.log(result.filePath)
    //   // })
    //
    //   // const answers = ['Yes', 'No', 'Maybe']
    //   // dialog.showMessageBox({
    //   //   title: 'Message Box',
    //   //   message: 'Please select an option',
    //   //   detail: 'Message details.',
    //   //   buttons: answers
    //   // }).then(({response}) => {
    //   //   console.log(`User selected: ${answers[response]}`)
    //   // })
    //
    //   // contextMenu.popup()
    // });
  });
  // getSQL();

  // 如果打包了，渲染index.html
  if (app.isPackaged) {
    win.loadFile(path.join(__dirname, "../index.html"));
  } else {
    const url = "http://localhost:5173"; // 本地启动的vue项目路径
    win.loadURL(url);
  }
};

app.whenReady().then(() => {
  createWindow(); // 创建窗口
  // testShell()
  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// 关闭窗口
app.on("window-all-closed", () => {
  // push 远程
  const settingPath = path.resolve(__dirname, "../src/common/data/setting.json");
  const filebuffer = fs.readFileSync(settingPath);
  const setting: Setting = JSON.parse(filebuffer.toString());
  commitGitProject(setting.git, setting.dataPath);
  setTimeout(() => {
    if (process.platform !== "darwin") {
      app.quit();
    }
  }, 10000);
});

app.on("quit", () => {
  console.log("quit");
});

// 读取path下的文件名称列表
function readDirSync(path: string) {
  const files: Array<string> = [];
  const pa = fs.readdirSync(path);
  pa.forEach(function (ele, __) {
    const info = fs.statSync(path + "/" + ele);
    if (info.isDirectory()) {
      //  console.log("dir: " + ele);
      readDirSync(path + "/" + ele);
    } else {
      //  console.log("file: " + ele);
      files.push(ele);
    }
  });
  return files;
}
/* 用于判断路径是否存在， 如果不存在，则创建一个 */
const mkdirPath = async (pathStr: string, content: string) => {
  // var projectPath = path.join(process.cwd());
  const tempDirArray = pathStr.split(path.sep);
  let projectPath = tempDirArray[0];
  // console.log(tempDirArray)
  for (let i = 1; i < tempDirArray.length; i++) {
    projectPath = projectPath + path.sep + tempDirArray[i];
    const flag = fs.existsSync(projectPath);
    if (!flag) {
      if (tempDirArray[i].indexOf(".") == -1) {
        fs.mkdirSync(projectPath);
      } else {
        if (content === undefined) content = "";
        fs.appendFile(projectPath, content, "utf-8", err => {
          if (err) return console.log("该文件不存在，重新创建失败！");
          console.log(projectPath + "文件不存在，已新创建");
        });
      }
    }
  }
  return projectPath;
};
function pullGitProject(gitProject: string, pathStr: string) {
  if (gitProject.length > 0) {
    let prefix = "";
    if (process.platform === "win32") prefix = "powershell ";
    // 拉取项目
    try {
      // 执行 ls 命令，并将结果保存在 result 变量中
      const result = execSync(prefix + "cd " + path.resolve(pathStr) + ";git pull;ls");
      console.log(result.toString()); // 将结果转换为字符串，并打印出来
      console.log("拉取项目成功");
    } catch (error) {
      console.log("拉取项目失败");
      console.error(error);
    }
    /**
     * function (err: any, stdout: any, stderr: any) {
     *       if (err) {
     *         console.log(err);
     *         console.log("拉取项目失败");
     *       } else {
     *         stdout;
     *         stderr;
     *         console.log("拉取项目成功");
     *       }
     *     }
     */
  }
}
function addGitProject(gitProject: string, pathStr: string) {
  if (gitProject.length > 0) {
    let prefix = "";
    if (process.platform === "win32") prefix = "powershell ";
    // 拉取项目
    exec(prefix + "cd " + path.resolve(pathStr) + ";git add .", function (err: any, stdout: any, stderr: any) {
      if (err) {
        console.log(err);
        console.log("git add 失败");
      } else {
        stdout;
        stderr;
        console.log("git add 成功");
      }
    });
  }
}
function commitGitProject(gitProject: string, pathStr: string) {
  if (gitProject.length > 0) {
    let prefix = "";
    if (process.platform === "win32") prefix = "powershell ";
    console.log(
      "setting++++++++++++++++",
      prefix + "cd " + path.resolve(pathStr) + ';git commit -a -m "' + DateUtils.generateUUID() + '"',
    );
    exec(
      prefix + "cd " + path.resolve(pathStr) + ';git commit -a -m "' + DateUtils.generateUUID() + '"',
      function (err: any, stdout: any, stderr: any) {
        if (err) {
          console.log(err);
          console.log("git commit 失败");
        } else {
          stdout;
          stderr;
          console.log("git commit 成功");
          pushGitProject(gitProject, pathStr);
        }
      },
    );
  }
}
function pushGitProject(gitProject: string, pathStr: string) {
  if (gitProject.length > 0) {
    let prefix = "";
    if (process.platform === "win32") prefix = "powershell ";
    exec(
      prefix + "cd " + path.resolve(pathStr) + ";git push " + gitProject + " master",
      function (err: any, stdout: any, stderr: any) {
        if (err) {
          console.log(err);
          console.log("git push 失败");
        } else {
          stdout;
          stderr;
          console.log("git push 成功");
        }
      },
    );
  }
}
ipcMain.handle("pull-git-project", async (event, gitProject: string, pathStr: string) => {
  pullGitProject(gitProject, pathStr);
});
ipcMain.handle("add-git-project", async (event, gitProject: string, pathStr: string) => {
  // await mkdirPath(path.resolve(dataPath, pathStr), "");
  addGitProject(gitProject, pathStr);
});
ipcMain.handle("commit-git-project", async (event, gitProject: string, pathStr: string) => {
  // await mkdirPath(path.resolve(dataPath, pathStr), "");
  commitGitProject(gitProject, pathStr);
});
ipcMain.handle("delete-file-list", async (event, pathStr: string) => {
  // 删除文件
  const pathStrList = JSON.parse(pathStr);
  for (let i = 0; i < pathStrList.length; i++) {
    const s = pathStrList[i];
    if (fs.existsSync(s)) {
      fs.unlinkSync(s);
      console.log(path + " File deleted!");
    }
  }
});
ipcMain.handle("get-file-full-path", async (event, dataPath: string, pathStr: string, paths: string) => {
  // console.log("get-file-base-path",dataPath,paths,pathStr)
  return JSON.parse(pathStr).map((s: any) => {
    // console.log(s.indexOf("http"),"++++++++++++++")
    if (s.indexOf("http") === -1) return path.resolve(dataPath, paths + s);
    else return s;
  });
});
ipcMain.handle("get-file-base-path", async (event, pathStr: string) => {
  const result = JSON.parse(pathStr).map((s: any) => {
    const str = s.split(path.sep);
    return str[str.length - 1];
  });
  // console.log("get-file-base-path",result,pathStr)
  return result;
});
ipcMain.handle("get-file-list", async (event, dataPath: string, pathStr: string) => {
  await mkdirPath(path.resolve(dataPath, pathStr), "");
  return readDirSync(path.resolve(dataPath, pathStr));
});
ipcMain.handle("save-to-file", async (event, dataPath: string, pathStr: string, content: string) => {
  // await mkdirPath(path.resolve(dataPath, pathStr), "");
  fs.writeFileSync(path.resolve(dataPath, pathStr), content);
});
ipcMain.handle("fresh", async (event, dataPath: string, pathStr: string) => {
  // const str = await mkdirPath(path.resolve(dataPath, pathStr), "");
  // console.log("fresh",str)
  const flag = fs.existsSync(path.resolve(dataPath, pathStr));
  console.log(path.resolve(dataPath, pathStr), flag);
  if (flag) {
    const filebuffer = fs.readFileSync(path.resolve(dataPath, pathStr));
    return filebuffer.toString();
  } else {
    await mkdirPath(path.resolve(dataPath, pathStr), "");
    return "";
  }
});
// ** 配置setting相关 **//
ipcMain.handle("fresh-setting", async () => {
  const settingPath = path.resolve(__dirname, "../src/common/data/setting.json");
  const flag = fs.existsSync(settingPath);
  let setting: Setting = new Setting("", "", "用户", 10);
  if (!flag) {
    await mkdirPath(settingPath, JSON.stringify(setting));
  } else {
    const filebuffer = fs.readFileSync(settingPath);
    setting = JSON.parse(filebuffer.toString());
  }
  pullGitProject(setting.git, setting.dataPath);
  // 为每个文件进行初始化
  for (const initPathElement of PathUtils.getInitPath()) {
    // console.log(initPathElement)
    const initPath = path.resolve(setting.dataPath, initPathElement[0].toString());
    await mkdirPath(initPath, JSON.stringify(initPathElement[1]));
  }
  return setting;
});
ipcMain.handle("save-setting", async (event, settingStr) => {
  console.log("args", settingStr);
  fs.writeFileSync(path.resolve(__dirname, "../src/common/data/setting.json"), settingStr);
});
ipcMain.handle("choose-dir-path", async (event, dir: string) => {
  const result = await dialog.showOpenDialog({
    buttonLabel: "选择",
    defaultPath: app.getPath("desktop"),
    properties: ["createDirectory", "openFile", "openDirectory"],
  });
  if (!result.canceled) {
    return path.resolve(result.filePaths[0], "./" + dir);
  } else return "";
});
ipcMain.handle("save-to-local", async (event, originalPtah: string, dir: string) => {
  // await mkdirPath(path.resolve(dataPath, pathStr), "");
  if (originalPtah.length > 0) {
    const str = originalPtah.split(path.sep);
    const fileName = str[str.length - 1];
    // const filebuffer = fs.readFileSync(originalPtah);
    // // console.log(dir, fileName,"++++++++++++++++++++++++=")
    // fs.writeFileSync(path.resolve(dir, fileName), filebuffer);
    fs.createReadStream(originalPtah).pipe(fs.createWriteStream(path.resolve(dir, fileName)));
  }
});
ipcMain.handle("choose-file-path", async (event, dataPath: string, pathStr: string) => {
  const dir = path.resolve(dataPath, pathStr);
  const list = new Array<string>();
  await mkdirPath(dir, "");
  const result = await dialog.showOpenDialog({
    buttonLabel: "选择",
    defaultPath: app.getPath("desktop"),
    properties: ["multiSelections", "openFile"],
  });
  if (!result.canceled) {
    console.log(result.filePaths);
    for (let i = 0; i < result.filePaths.length; i++) {
      const p = result.filePaths[i];
      const strings = p.split(".");
      console.log(strings);
      if (strings.length === 2) {
        const prefix = strings[1];
        const uuid = DateUtils.generateUUID();
        const filebuffer = fs.readFileSync(p);
        const fileName = uuid + "." + prefix;
        fs.writeFileSync(path.resolve(dir, fileName), filebuffer);
        list.push(path.resolve(dir, fileName));
        // list.push(p)
      }
    }
  }
  return list;
});

// ** 文件存储 **//
// 文件存储： 在程序内部会存储一个setting.json文件，里面记录数据文件位置，git信息等
/**
 * --data
 *  -- maxId.json
 *  -- surfaceSetting.json
 *  -- lifeModel.json
 *  -- timeManage.json
 *  -- fieldData.json
 *  -- stageData.json
 *  -- finishStageData
 *    -- fieldId.json
 *  -- taskData.json
 *  -- taskLog
 *    -- yyyyMM.json 202307.json
 *  -- memory.json
 *  -- statistic
 *    -- id.json
 *  -- file
 *    -- pic
 *      -- UUID.png/jpg/avi
 *    -- markDown
 *      -- UUID.md
 */
ipcMain.handle("get-all-data", () => {
  const filebuffer = fs.readFileSync(path.resolve(__dirname, "../src/common/data/setting.json"));
  const setting: Setting = JSON.parse(filebuffer.toString());
  return {
    setting,
    fieldData: {
      fieldTree: [
        {
          id: 6,
          children: [
            {
              id: 7,
              children: [],
            },
            {
              id: 8,
              children: [
                {
                  id: 9,
                  children: [],
                },
              ],
            },
          ],
        },
      ],
      fieldData: {
        "6": {
          id: 6,
          name: "文件夹",
          goalIds: [10],
        },
        "7": {
          id: 7,
          name: "空的",
          goalIds: [],
        },
        "8": {
          id: 8,
          name: "我的文件",
          goalIds: [],
        },
        "9": {
          id: 9,
          name: "template.txt",
          goalIds: [],
        },
      },
      data: {
        "6": {
          id: 6,
          name: "文件夹",
          stageIds: {
            进行中: [],
            未进行: [],
            已结束: [],
          },
          markDownFile: "",
          isStageGoingOn: false,
        },
        "7": {
          id: 7,
          name: "空的",
          stageIds: {
            进行中: [],
            未进行: [],
            已结束: [],
          },
          markDownFile: "",
          isStageGoingOn: false,
        },
        "8": {
          id: 8,
          name: "我的文件",
          stageIds: {
            进行中: [],
            未进行: [],
            已结束: [],
          },
          markDownFile: "",
          isStageGoingOn: false,
        },
        "9": {
          id: 9,
          name: "template.txt",
          stageIds: {
            进行中: [11, 12],
            未进行: [],
            已结束: [],
          },
          markDownFile: "",
          isStageGoingOn: false,
        },
      },
    },
    stageData: {
      "11": {
        id: 11,
        name: "第一个阶段",
        takeTime: 0,
        lastStartTime: 0,
        fatherId: 9,
        startTime: [
          {
            start: 0,
            end: 0,
          },
        ],
        task: {
          "1": {
            进行中: [15],
            未进行: [],
            已完成: [],
          },
          "2": {
            进行中: [],
            未进行: [],
            已完成: [],
          },
        },
        file: "",
      },
      "12": {
        id: 12,
        name: "第2个阶段",
        takeTime: 0,
        lastStartTime: 0,
        startTime: [
          {
            start: 0,
            end: 0,
          },
        ],
        task: {
          "1": {
            进行中: [],
            未开始: [],
            已完成: [],
          },
          "2": {
            进行中: [],
            未开始: [],
            已完成: [],
          },
        },
        file: "",
      },
    },
    finishStageData: {
      "1": {
        "14": {
          id: 14,
          name: "第0个阶段",
          takeTime: 0,
          lastStartTime: 0,
          startTime: [
            {
              start: 0,
              end: 0,
            },
          ],
          task: {
            "1": {
              进行中: [],
              未进行: [],
              已完成: [
                {
                  id: 15,
                  type: 1,
                  takeTime: 0,
                  status: "未进行",
                  deadLine: 0, // 截止日期
                  beforeDDL2Metion: 0, // 在截止日期前多久提醒
                  beginMentionTime: 0, // 第一次打卡时间，用于习惯性任务
                  mentionFlag: 1, // 提醒周期标志，是每：1，还是自定义:2
                  mentionPeriod: "1", // 提醒周期。若是自定义，则以逗号分割，例如1,2,3代表隔
                  mentionPos: "1", //自定义时，代表处在第几个
                  mentionUnit: "1", //提醒周期单位，例如1代表天，2代表月，3代表年,
                  fatherId: 9,
                },
              ],
            },
            "2": {
              进行中: [],
              未进行: [],
              已完成: [],
            },
          },
          file: "",
        },
      },
    },
    taskData: {
      "13": {
        id: 13,
        type: 1,
        takeTime: 0,
        status: "未进行",
        deadLine: 0, // 截止日期
        beforeDDL2Mention: 0, // 在截止日期前多久提醒
        beginMentionTime: 0, // 第一次打卡时间，用于习惯性任务
        mentionFlag: 1, // 提醒周期标志，是每：1，还是自定义:2
        mentionPeriod: "1", // 提醒周期。若是自定义，则以逗号分割，例如1,2,3代表隔
        mentionPos: "1", //自定义时，代表处在第几个
        mentionUnit: "1", //提醒周期单位，例如1代表天，2代表月，3代表年,
        fatherId: 9,
        subTask: [{ name: "第一个子任务" }],
      },
    },
    taskLog: {
      "202307": {
        "20230723": {
          "20230723003406": {
            id: "20230723003406",
            type: "生活/临时/普通",
            taskId: 13, // 标签
            startTime: 0,
            endTime: 0,
            takeTime: 0,
            markDownFile: "",
            mediaList: [],
            location: "",
          },
        },
      },
    },
    memory: ["20230723003406"],
    statistic: {
      "13": {
        "20230723": ["20230723003406"],
        "20230724": ["20230723003406"],
      },
    },
  };
});
